﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using web.data.entities;
using System.Configuration;
using Webdiyer.WebControls.Mvc;
using System.Web.UI;

namespace web.bussines
{
    public class account_service
    {
       
        public users getUserByID(int id)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.user_id == id).FirstOrDefault();

                return user;
            }
        }

        public users authenticateUser(string user_name, string password)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.username == user_name && p.password == password && p.user_status==1).SingleOrDefault();
                return user;
            }
        }

        public users authenticateUserEmail(string email, string password)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.email == email && p.password == password && p.user_status==1).SingleOrDefault();
                return user;
            }
        }

        public int countUserByUserName(string user_name)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.username == user_name);
                return user.Count();
            }
        }

        public List<page> getListPageAccessByUser(int id)
        {
            using (var data = new baseEntities())
            { 
                var list_page=(from u in data.tbl_users
                              join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                              from e0 in r0.DefaultIfEmpty()
                              join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                              from e1 in r1.DefaultIfEmpty()
                              join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                              from e2 in r2.DefaultIfEmpty()
                              join p in data.tbl_page on e2.page_id equals p.page_id 
                              where u.user_id==id && p.page_status==1
                              select p);

                return list_page.ToList();
            }
        }

        public bool checkPageAccessByUser(int id,string page_path)
        {
            using (var data = new baseEntities())
            {
                var list_page = (from u in data.tbl_users
                                 join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                 from e0 in r0.DefaultIfEmpty()
                                 join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                 from e1 in r1.DefaultIfEmpty()
                                 join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                 from e2 in r2.DefaultIfEmpty()
                                 join p in data.tbl_page on e2.page_id equals p.page_id
                                 where u.user_id == id && p.page_status == 1 && p.page_path==page_path && e1.group_enable==true
                                 select p).ToList();
                if (list_page.Count > 0)
                    return true;
                return false;
            }
        }

        public List<int> getListPageAccessByGroup(int id)
        {
            using (var data = new baseEntities())
            {
                var list_page = (from u in data.tbl_user_group 
                                 join pr in data.tbl_page_role on u.group_id equals pr.group_id into r2
                                 from e2 in r2.DefaultIfEmpty()
                                 join p in data.tbl_page on e2.page_id equals p.page_id
                                 where u.group_id == id && p.page_status == 1
                                 select p.page_id);

                return list_page.ToList();
            }
        }

        public void changePassword(users user)
        {
            using (var data = new baseEntities())
            {
                var user_change_password = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();

                user_change_password.password = user.password;
                user_change_password.salt = user.salt;
                data.SaveChanges();
            }
        }

        public void updateStatusUser(users user)
        {
            using (var data = new baseEntities())
            {
                var user_change_status = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();

                user_change_status.user_status = user.user_status;
                data.SaveChanges();
            }
        }

        public int createUser(users user)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_users(user);
                data.SaveChanges();

                return user.user_id;
            }
        }

        public void editUser(users user)
        {
            using (var data = new baseEntities())
            {
                var edit_user = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();

                edit_user.username = user.username;
                edit_user.password = user.password;
                edit_user.activation_code = user.activation_code;
                edit_user.active_date = user.active_date;
                edit_user.created_date = user.created_date;
                edit_user.email = user.email;
                edit_user.salt = user.salt;
                edit_user.user_status = user.user_status;
                data.SaveChanges();
            }
        }

        public List<users> getListUser(int startRecord, int pageSize,out int total)
        {
            using (var data = new baseEntities())
            {
                total = data.tbl_users.OrderByDescending(p => p.user_id).Count();
                var list_user = data.tbl_users.OrderByDescending(p => p.user_id).Skip(startRecord).Take(pageSize).ToList();
                return list_user;
            }
        }

        public PagedList<users> getPageListUser(int pageindex, int pagesite, string text_search, int? group_id)
        {
            using (var data = new baseEntities())
            {
                IQueryable<users> list;
                if (group_id != null && group_id!=0)
                {
                    list = (from p in data.tbl_users
                            join urf in data.tbl_user_ref_roles on p.user_id equals urf.user_id
                            where urf.group_id == group_id
                            select p);
                }
                else
                {
                    list = (from p in data.tbl_users
                            select p);
                }

                if (!string.IsNullOrEmpty(text_search))
                {
                    list = list.Where(p => p.username.Contains(text_search) || p.email.Contains(text_search));
                }

                list = list.OrderByDescending(p => p.user_id);

                return list.ToPagedList(pageindex,pagesite);
            }
        }

        public List<user_group> getListUserGroup()
        {
            using (var data = new baseEntities())
            {
                var list_group = data.tbl_user_group.Where(p=>p.group_enable==true).OrderBy(p => p.group_id).ToList();
                return list_group;
            }
        }

        public void addGroupForUser(int group_id, int user_id)
        {
            using (var data = new baseEntities())
            {
                var check = data.tbl_user_ref_roles.Where(p => p.group_id == group_id && p.user_id == user_id);
                if (check==null || check.Count() == 0)
                {
                    user_ref_roles urr = new user_ref_roles();
                    urr.group_id = group_id;
                    urr.user_id = user_id;
                    urr.date_from = DateTime.Now;

                    data.AddTotbl_user_ref_roles(urr);
                    data.SaveChanges();
                }
            }
        }

        public void deleteUserFromGroup(int group_id, int user_id)
        {
            using (var data = new baseEntities())
            {
                user_ref_roles urr = data.tbl_user_ref_roles.Where(p => p.group_id == group_id && p.user_id == user_id).FirstOrDefault();

                if (urr != null)
                {
                    data.DeleteObject(urr);
                    data.SaveChanges();
                }
            }
        }

        public void deleteAllGroupOfUser(int user_id)
        {
            using (var data = new baseEntities())
            {
                var list = data.tbl_user_ref_roles.Where(p => p.user_id == user_id).ToList();
                foreach (var item in list)
                {
                    data.DeleteObject(item);
                    data.SaveChanges();
                }
            }
        }

        public List<int> getListGroupOfUser(int user_id)
        {
            using (var data = new baseEntities())
            {
                var list_group_id = (from p in data.tbl_user_ref_roles
                                     join g in data.tbl_user_group on p.group_id equals g.group_id
                                     where p.user_id==user_id && g.group_enable==true
                                     select (int)p.group_id).ToList();
                return list_group_id;
            }
        }

        public PagedList<user_group> getPageListGroup(int pageindex, int pagesite, string text_search)
        {
            using (var data = new baseEntities())
            {
                IQueryable<user_group> list;
               
                list = (from p in data.tbl_user_group
                            select p);
                
                if (!string.IsNullOrEmpty(text_search))
                {
                    list = list.Where(p => p.group_name.Contains(text_search) || p.group_desc.Contains(text_search));
                }

                list = list.OrderByDescending(p => p.group_id);

                return list.ToPagedList(pageindex, pagesite);
            }
        }

        public void updateStatusGroup(user_group group)
        {
            using (var data = new baseEntities())
            {
                var group_change_enable = data.tbl_user_group.Where(p => p.group_id == group.group_id).SingleOrDefault();

                group_change_enable.group_enable = group.group_enable;
                data.SaveChanges();
            }
        }

        public page getPageByID(int id)
        {
            using (var data = new baseEntities())
            {
                var page = data.tbl_page.Where(p => p.page_id == id).FirstOrDefault();
                return page;
            }
        }

        public List<page> getListPageByParent(int? id)
        {
            using (var data = new baseEntities())
            {
                var list_page = data.tbl_page.Where(p => p.page_status == 1);

                if (id != null)
                {
                    list_page = list_page.Where(p => p.page_parent == id);
                }
                else
                {
                    list_page = list_page.Where(p => p.page_parent == null);
                }

                return list_page.ToList();
            }
        }

        public PagedList<page> getPagerBuilder(int pageindex, int pagesite, string text_search,int? parent)
        {
            using (var data = new baseEntities())
            {
                IQueryable<page> list=getListPageBuilder(parent).AsQueryable<page>();

                if (!string.IsNullOrEmpty(text_search))
                {
                    list = list.Where(p => p.page_name.Contains(text_search) || p.page_path.Contains(text_search) || p.page_desc.Contains(text_search));
                }

                list = list.OrderBy(p => p.page_order);

                return list.ToPagedList(pageindex, pagesite);
            }
        }

        public List<page> getListPageBuilder(int? id)
        {
            List<page> sb = new List<page>();
            return getListPageBuilder(ref sb, id, true);
        }

        public List<page> getListPageBuilder(ref List<page> sb, int? id, bool root)
        {
            List<page> list_parent = getListPageByParent(id);
            foreach (var item in list_parent)
            {
                if (!root)
                {
                    item.page_name = getPageByID((int)item.page_parent).page_name + ">>" + item.page_name;
                    page pa = getPageByID(id??0);
                    foreach (var itemStr in sb)
                    {
                        if (itemStr.page_id == pa.page_id)
                        {
                            if (itemStr.page_name.Contains(">>"))
                            {
                                int laststr = itemStr.page_name.LastIndexOf(">>") + 2;
                                string addStr = itemStr.page_name.Substring(0, laststr);
                                item.page_name = addStr + item.page_name;
                            }
                        }
                    }
                }
                sb.Add(item);
                List<page> list_child = getListPageByParent(item.page_id);
                if (list_child.Count() > 0)
                {
                    getListPageBuilder(ref sb, item.page_id, false);
                }
            }
            return sb;
        }

        public void updateStatusPage(page page)
        {
            using (var data = new baseEntities())
            {
                var page_change_status = data.tbl_page.Where(p => p.page_id == page.page_id).SingleOrDefault();

                page_change_status.page_status = page.page_status;
                data.SaveChanges();
            }
        }

        public int createPage(page page)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_page(page);
                data.SaveChanges();

                return page.page_id;
            }
        }

        public void editPage(page page)
        {
            using (var data = new baseEntities())
            {
                var edit_page = data.tbl_page.Where(p => p.page_id == page.page_id).SingleOrDefault();

                edit_page.page_name = page.page_name;
                edit_page.page_desc = page.page_desc;
                edit_page.page_path = page.page_path;
                edit_page.page_order = page.page_order;
                edit_page.page_status = page.page_status;
                edit_page.page_type = page.page_type;
                edit_page.page_parent = page.page_parent;
                data.SaveChanges();
            }
        }

        public user_group getGroupByID(int id)
        {
            using (var data = new baseEntities())
            {
                var group = data.tbl_user_group.Where(p => p.group_id == id).FirstOrDefault();
                return group;
            }
        }

        public List<user_group> getListGroupByParent(int? id)
        {
            using (var data = new baseEntities())
            {
                var list_group = data.tbl_user_group.Where(p => p.group_enable == true);

                if (id != null)
                {
                    list_group = list_group.Where(p => p.group_parent_id == id);
                }
                else
                {
                    list_group = list_group.Where(p => p.group_parent_id == null);
                }

                return list_group.ToList();
            }
        }

        public List<user_group> getListGroupBuilder(int? id)
        {
            List<user_group> sb = new List<user_group>();
            return getListGroupBuilder(ref sb, id, true);
        }

        public List<user_group> getListGroupBuilder(ref List<user_group> sb, int? id, bool root)
        {
            List<user_group> list_parent = getListGroupByParent(id);
            foreach (var item in list_parent)
            {
                if (!root)
                {
                    item.group_name = getGroupByID((int)item.group_parent_id).group_name + ">>" + item.group_name;
                    user_group gr = getGroupByID(id ?? 0);
                    foreach (var itemStr in sb)
                    {
                        if (itemStr.group_id == gr.group_id)
                        {
                            if (itemStr.group_name.Contains(">>"))
                            {
                                int laststr = itemStr.group_name.LastIndexOf(">>") + 2;
                                string addStr = itemStr.group_name.Substring(0, laststr);
                                item.group_name = addStr + item.group_name;
                            }
                        }
                    }
                }
                sb.Add(item);
                List<user_group> list_child = getListGroupByParent(item.group_id);
                if (list_child.Count() > 0)
                {
                    getListGroupBuilder(ref sb, item.group_id, false);
                }
            }
            return sb;
        }

        public int createGroup(user_group group)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_user_group(group);
                data.SaveChanges();

                return group.group_id;
            }
        }

        public void editGroup(user_group group)
        {
            using (var data = new baseEntities())
            {
                var edit_group = data.tbl_user_group.Where(p => p.group_id == group.group_id).SingleOrDefault();

                edit_group.group_name = group.group_name;
                edit_group.group_desc = group.group_desc;
                edit_group.group_enable = group.group_enable;
                edit_group.group_parent_id = group.group_parent_id;
                data.SaveChanges();
            }
        }

        public void deleteAllPageAccessOfGroup(int group_id)
        {
            using (var data = new baseEntities())
            {
                var list = data.tbl_page_role.Where(p => p.group_id == group_id).ToList();
                foreach (var item in list)
                {
                    data.DeleteObject(item);
                    data.SaveChanges();
                }
            }
        }

        public void createAccessPageforGroup(int group_id,string arr_page)
        {
            using (var data = new baseEntities())
            {
                var arr_page_id = arr_page.Split(',');
                foreach (var item in arr_page_id)
                {
                    page_role pr = new page_role();
                    pr.group_id = group_id;
                    pr.page_id = int.Parse(item);
                    pr.created_date = DateTime.Now;

                    data.AddTotbl_page_role(pr);
                    data.SaveChanges();
                }
            }
        }

        public List<page> getListTopPageParent(int id)
        {
            using (var data = new baseEntities())
            {
                var list_page_access = (from u in data.tbl_users
                                        join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                        from e0 in r0.DefaultIfEmpty()
                                        join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                        from e1 in r1.DefaultIfEmpty()
                                        join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                        from e2 in r2.DefaultIfEmpty()
                                        join p in data.tbl_page on e2.page_id equals p.page_id
                                        where u.user_id == id && p.page_status == 1 && p.page_parent == null
                                        select p);

                return list_page_access.ToList();
            }
        }

        public List<page> getListMenuPageByTopPageID(int? id,int user_id)
        {
            using (var data = new baseEntities())
            {
                var list_page_access = getListPageByParentID(id, user_id);

                return list_page_access.ToList();
            }
        }

        public List<page> getListPageByParentID(int? id, int user_id)
        {
            using (var data = new baseEntities())
            {
                var list_page_access = (from u in data.tbl_users
                                        join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                        from e0 in r0.DefaultIfEmpty()
                                        join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                        from e1 in r1.DefaultIfEmpty()
                                        join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                        from e2 in r2.DefaultIfEmpty()
                                        join p in data.tbl_page on e2.page_id equals p.page_id
                                        where u.user_id == user_id && p.page_status == 1 && p.page_type==1 && p.page_parent == id
                                        select p);

                return list_page_access.ToList();
            }
        }

        public HtmlTextWriter getListPageMenuBuilder(int? id, int user_id, string uri)
        {
            HtmlTextWriter sb = new HtmlTextWriter(new System.IO.StringWriter());
            return getListPageMenuBuilder(ref sb, id, user_id, true, uri);
        }

        public HtmlTextWriter getListPageMenuBuilder(ref HtmlTextWriter sb, int? id, int user_id, bool root, string uri)
        {
            Uri nuri = new Uri(uri);
            var arr = nuri.PathAndQuery.Split('/');

            List<page> list_parent = getListPageByParentID(id, user_id);
            if (root)
            {
                sb.WriteBeginTag("ul");
                sb.Write(">");
            }
            else
            {
                sb.WriteBeginTag("ul");
                sb.WriteAttribute("id", "addons");
                sb.Write(">");
            }
            sb.Write("\n");
            foreach (var item in list_parent)
            {

                sb.WriteBeginTag("li");
                if (root)
                {
                    if (uri.Contains(item.page_path))
                    {
                        sb.WriteAttribute("class", "current");
                    }
                }
                sb.Write(">");
                List<page> list_child = getListPageByParentID(item.page_id, user_id);
                sb.WriteBeginTag("a");
                sb.WriteAttribute("href", "/vi"+item.page_path);
                sb.Write(">");
                sb.Write(item.page_name);
                sb.WriteEndTag("a");
                if (list_child.Count() > 0)
                {
                    sb.WriteBeginTag("span");
                    sb.WriteAttribute("class", "arrow");
                    sb.Write(">");
                        sb.WriteBeginTag("a");
                        sb.WriteAttribute("href", "#" + item.page_id);
                        sb.Write(">");
                        sb.Write("&nbsp;");
                        sb.WriteEndTag("a");
                    sb.WriteEndTag("span");

                    sb.WriteBeginTag("ul");
                    sb.WriteAttribute("id", ""+item.page_id);
                    sb.Write(">");
                    sb.Write("\n");
                    foreach (var page in list_child)
                    {
                        sb.WriteBeginTag("li");
                        if (uri.Contains(page.page_path))
                        {
                            sb.WriteAttribute("class", "current");
                        }
                        sb.Write(">");
                        sb.WriteBeginTag("a");
                        sb.WriteAttribute("href", "/vi"+page.page_path);
                        sb.Write(">");
                        sb.Write(page.page_name);
                        sb.WriteEndTag("a");
                        sb.WriteEndTag("li");

                        sb.Write("\n");
                    }
                    sb.WriteEndTag("ul");
                    sb.Write("\n");

                }
                sb.WriteEndTag("li");
                sb.Write("\n");
            }
            sb.WriteEndTag("ul");

            return sb;
        }

        public int getTotalMaleEmployee()
        {
            using (var data = new baseEntities())
            {
                var result = (from p in data.employees
                              where (p.gender == true)&&p.employee_status==1
                              select p);
                return result.Count();
            }
        }

        public int getTotalFemaleEmployee()
        {
            using (var data = new baseEntities())
            {
                var result = (from p in data.employees
                              where (p.gender == false || p.gender==null)&&p.employee_status==1
                              select p);
                return result.Count();
            }
        }
    }
}
